﻿using System;
using System.Text.RegularExpressions;
using Charades.Web.Controllers;
using Charades.Web.Helpers;
using Microsoft.AspNet.Identity;

namespace Charades.Web.Hubs
{
	using System.Linq;
	using System.Web;
	using System.Web.Helpers;

	using Charades.Web.Server.Room;
	using Charades.Web.Server.User;

	public class GameHub : BaseHub
	{
		/// <summary>
		/// Инициализация пользователя
		/// </summary>
		/// <param name="name">Имя пользователя</param>
		/// <returns>Сущьность полльзователя</returns>
		public object InitializeUser(string name)
		{
			if (string.IsNullOrEmpty(name) || !Regex.IsMatch(name, "^[А-яA-z0-9_-]{3,15}$"))
			{
				return null;
			}

			if (Context.User != null && Context.User.Identity.IsAuthenticated)
			{
				var user = UserManager.FindByName(Context.User.Identity.Name);
				return Game.InitializeUser(
					Context.ConnectionId,
					user.DisplayName,
					user.Color,
					user.UserName);
			}

			return Game.InitializeUser(
				Context.ConnectionId,
				name);
		}

		/// <summary>
		/// Возвращает список пользователей
		/// </summary>
		/// <returns></returns>
		public object GetUsers()
		{
			return Game.UserHandler.GetUsers();
		}

		/// <summary>
		/// Возвращает колличество пользователей
		/// </summary>
		/// <returns></returns>
		public object GetUsersCount()
		{
			return Game.UserHandler.GetUsersCount();
		}

		/// <summary>
		/// Поиск открытой комнаты для пользователя
		/// </summary>
		public object CreateRoom(string roomId)
		{
			if (Regex.IsMatch(roomId, @"[a-zA-Z0-9]{5}$") && !Game.RoomHandler.CheckRoom(roomId))
			{
				Game.RoomHandler.CreateRoom(roomId);
				return new { success = true };
			}
			return new { success = false };
		}

		/// <summary>
		/// Поиск открытой комнаты для пользователя
		/// </summary>
		public void FindRoom()
		{
			if (!Game.UserHandler.IsBanned(Context.ConnectionId))
			{
				FindRoom(string.Empty);
			}
		}

		/// <summary>
		/// Поиск комнаты для пользователя
		/// </summary>
		public void FindRoom(string roomId)
		{
			var room = Game.RoomHandler.GetRoom(Context.ConnectionId);
			if (Game.UserHandler.UserExists(Context.ConnectionId) && room == null || (room != null && room.Status == RoomStatus.Finished))
			{
				Game.FindRoom(Context.ConnectionId, roomId);
			}
		}

		/// <summary>
		/// Входящие соообщение
		/// </summary>
		/// <param name="msg">Сообщение</param>
		public void SendMessage(string msg)
		{
			if (!string.IsNullOrEmpty(msg) && Game.UserHandler.UserExists(Context.ConnectionId) && !Game.RoomHandler.UserCanDraw(Context.ConnectionId))
			{
				Game.SendMessage(Context.ConnectionId, HttpUtility.HtmlEncode(msg.Length > 140 ? msg.Substring(0, 140) : msg));
			}
		}

		/// <summary>
		/// Рисование
		/// </summary>
		/// <param name="data">Данные рисования</param>
		public void Draw(string data)
		{
			if (!string.IsNullOrEmpty(data) && Game.UserHandler.UserExists(Context.ConnectionId) && Game.RoomHandler.UserCanDraw(Context.ConnectionId))
			{
				var user = Game.UserHandler.GetUser(Context.ConnectionId);
				Clients.Group(user.RoomId, Context.ConnectionId).draw(data);
			}
		}

		/// <summary>
		/// Начать раунд
		/// </summary>
		/// <param name="wordId">ID слова</param>
		public void StartRound(int wordId)
		{
			if (Game.UserHandler.UserExists(Context.ConnectionId))
			{
				Game.StartRound(Context.ConnectionId, wordId);
			}
		}

		/// <summary>
		/// Возвращает список пользователей в комнате
		/// </summary>
		/// <returns>Список пользователей</returns>
		public object GetUsersList()
		{
			if (Game.UserHandler.UserExists(Context.ConnectionId))
			{
				var room = Game.RoomHandler.GetRoom(Context.ConnectionId);
				if (room != null)
				{
					return room.Users.OrderBy(u => u.Points);
				}
			}

			return null;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="userId"></param>
		public void UserBan(string userId)
		{
			if (Game.UserHandler.UserExists(Context.ConnectionId))
			{
				Game.UserBan(Context.ConnectionId, userId);
			}
		}
	}
}